package gnss

import (
	"dgo/goutils/utils"
	"math"
)

type IgsSSR_IGM03 struct {
	SatId          byte
	IOD            byte
	RadialD        float64
	AlongTrackD    float64
	CrossTrackD    float64
	RadialDotD     float64
	AlongTrackDotD float64
	CrossTrackDotD float64
	ClockC0D       float64
	ClockC1D       float64
	ClockC2D       float64
}

type IgsSSR_IGM03_List [SATID_MAX]IgsSSR_IGM03

func (this *IgsSSR_IGM03_List) CheckGetSat(satid byte) *IgsSSR_IGM03 {
	sat := &this[satid-1]
	if sat.SatId != satid {
		sat.SatId = satid
	}
	return sat
}

/*
Satellite Specific Part of the GNSS SSR Combined Orbit and Clock Correction Message IGM03
*/
func EncodeSSR4Sat(lst *IgsSSR_IGM03_List, bb *utils.BytesBuilder, startByteN int, startBitN int) int {
	for i := 0; i < len(lst); i++ {
		rec := lst[i]
		if rec.SatId > 0 {
			bb.CheckSize(startByteN, (startBitN+205)/8+1)
			// GNSS Satellite ID
			bb.SetBitU8(startByteN, startBitN, 6, byte(rec.SatId))
			startBitN += 6

			/* GNSS IOD */
			bb.SetBitU8(startByteN, startBitN, 8, rec.IOD)
			startBitN += 8

			/* Delta Orbit Radial */
			bb.SetBitI32(startByteN, startBitN, 22, int32(math.Round(rec.RadialD/1e-4)))
			startBitN += 22

			/* Delta Orbit Along-Track */
			bb.SetBitI32(startByteN, startBitN, 20, int32(math.Round(rec.AlongTrackD/4e-4)))
			startBitN += 20

			/* Delta Orbit Cross-Track */
			bb.SetBitI32(startByteN, startBitN, 20, int32(math.Round(rec.CrossTrackD/4e-4)))
			startBitN += 20

			/* Dot Orbit Delta Radial */
			bb.SetBitI32(startByteN, startBitN, 21, int32(math.Round(rec.RadialDotD/1e-6)))
			startBitN += 21

			/* Dot Orbit Delta Along-Track */
			bb.SetBitI32(startByteN, startBitN, 19, int32(math.Round(rec.AlongTrackDotD/4e-6)))
			startBitN += 19

			/* Dot Orbit Delta Cross-Track */
			bb.SetBitI32(startByteN, startBitN, 19, int32(math.Round(rec.CrossTrackDotD/4e-6)))
			startBitN += 19

			/* delta clock C0 */
			bb.SetBitI32(startByteN, startBitN, 22, int32(math.Round(rec.ClockC0D/1e-4)))
			startBitN += 22

			/* delta clock C1 */
			bb.SetBitI32(startByteN, startBitN, 21, int32(math.Round(rec.ClockC1D/1e-6)))
			startBitN += 21

			/* delta clock C2 */
			bb.SetBitI32(startByteN, startBitN, 27, int32(math.Round(rec.ClockC2D/2e-8)))
			startBitN += 27
		}
	}

	return startBitN
}
